Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Xsl
Imports System.Xml.XPath
Imports System.Xml.Schema

Public Class Core

    Private ReadOnly _StyleSheet As StyleSheet
    Private ReadOnly _DocumentType As DocumentType

    Public Sub New(ByVal folder As String)

        Dim xslFolder As String = Path.Combine(folder, "xsl")
        Dim dtdFolder As String = Path.Combine(folder, "dtd")

        _StyleSheet = New StyleSheet(xslFolder)
        _DocumentType = New DocumentType(dtdFolder)

    End Sub

    Public Function DtdValidate(ByVal xmlWithoutDtd As String, ByVal name As String) As Boolean

        Return _DocumentType.Validate(xmlWithoutDtd, name) Is Nothing

    End Function

    Public Function GetInfoList(ByVal tool As String, ByVal keys() As String, ByVal i18n As String, ByVal xmlFile As String) As String

        Dim xmlData As MemoryStream

        'dtd validation
        Dim xmlWithoutDtd As String = LoadXmlWithoutDtd(xmlFile)
        Dim eventList As List(Of ValidationEventArgs) = _DocumentType.Validate(xmlWithoutDtd, DocumentType.DOCTYPE_INFO_LIST)
        If eventList.Count > 0 Then
            Dim sb As New StringBuilder()
            sb.AppendLine("invalid xml document type:")
            For Each e As ValidationEventArgs In eventList
                sb.AppendLine(e.Message)
            Next
            Throw New ApplicationException(sb.ToString())
        End If

        'filter service tools
        Try
            Dim sr As New StringReader(xmlWithoutDtd)
            Dim reader As XmlReader = XmlReader.Create(sr)

            Dim params As New XsltArgumentList()
            params.AddParam("tool", "", tool)
            params.AddParam("i18n", "", i18n)

            xmlData = Transform(_StyleSheet.ToolFilter, reader, params)
        Catch ex As Exception
            Throw ex
        End Try

        'filter keywords
        If keys.Length > 0 Then
            Dim index As Integer = 1

            For Each keyword As String In keys
                Dim reader As XmlReader = XmlReader.Create(xmlData)

                Dim name As String = "key " & index

                Dim params As New XsltArgumentList()
                params.AddParam("name", "", name)
                params.AddParam("value", "", keyword)

                xmlData = Transform(_StyleSheet.KeyFilter, reader, params)

                index += 1
            Next
        End If

        'something that tms190 does
        Try
            Dim reader As XmlReader = XmlReader.Create(xmlData)

            xmlData = Transform(_StyleSheet.FilelistXsl, reader, Nothing)
        Catch ex As Exception
            Throw ex
        End Try

        Return New StreamReader(xmlData).ReadToEnd()

    End Function

    Private Function LoadXmlWithoutDtd(ByVal uri As String) As String

        Dim xmlString As String
        Using reader As New StreamReader(uri)
            xmlString = reader.ReadToEnd()
        End Using

        Dim xmlWithoutDTD As String = DocumentType.RemoveDocType(xmlString)

        Return xmlWithoutDTD

    End Function

    Private Function Transform(ByVal xsl As XslCompiledTransform, ByVal reader As XmlReader, ByVal params As XsltArgumentList) As MemoryStream

        Dim ms As New MemoryStream()
        xsl.Transform(reader, params, ms)
        ms.Position = 0

        Return ms

    End Function
End Class
